#region File Description
//  XAEnima 
//  License: GNU/GPL
//  Developer: Federico Leonardo Motta
//  File description: This Screen is used to train users with SSVEP BCI
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using XAEnima.Core.GameManager;
using XAEnima.Core.Stimulation.Tipi;
using XAEnima.Core.Stimulation.External;
#endregion


namespace XAEnima.Core.Screens.Test
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Training : Microsoft.Xna.Framework.DrawableGameComponent
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        bool OldState = false;
        float screenscale;
        Rectangle area;
        Matrix SpriteScale;
        IInputManager InputManagerService;
        StimulationManager sm;
        IComunicationManager sender;
        SpriteFont font;
        LEDDriver led;
        Texture2D current, left, right, up, down, center;
        List<Vector2> posizioni;
        Vector2 pos = new Vector2();
        //const int TRAINING_SEQUENCE[] = {LEFT,NONE,UP,NONE,RIGHT,NONE,DOWN};
        Dictionary<string, int> TESTINGSEQUENCE = new Dictionary<string, int> { { "LEFT", 1 }, { "UP", 16 }, { "RIGHT", 8 }, { "DOWN", 32 } };
        Int16 countSequence = 0;
        short[] freq = new short[4];
        Boolean stim = false, isFirstime = true;
        float time = 0;

        public event TestAction OnBack;

        public Training(Game game)
            : base(game)
        {
            graphics = StateManager.graphic;
            InputManagerService = (IInputManager)Game.Services.GetService(typeof(IInputManager));
            InputManagerService.SPressed += new PressedEventHandler(SIsPressed);
            InputManagerService.SReleased += new PressedEventHandler(SIsReleased);
            InputManagerService.XPressed += new PressedEventHandler(XIsPressed);
            /* InputManagerService.EnterPressed += new PressedEventHandler(EnterIsPressed);
             InputManagerService.EnterReleased += new PressedEventHandler(EnterIsReleased);
             InputManagerService.TabPressed += new PressedEventHandler(TabIsPressed);
             InputManagerService.UpPressed += new PressedEventHandler(UpIsPressed);
             InputManagerService.DownPressed += new PressedEventHandler(DownIsPressed);*/
            sm = new StimulationManager(Game);
            posizioni = new List<Vector2>();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            screenscale = (float)(Game.GraphicsDevice.Viewport.Width / 1600f);
            spriteBatch = (Game.Services.GetService(typeof(SharedContext)) as SharedContext).sprite_batch;
            sender = (IComunicationManager)Game.Services.GetService(typeof(IComunicationManager));
            area = Game.GraphicsDevice.Viewport.TitleSafeArea;
            Game.IsFixedTimeStep = true;
            Game.TargetElapsedTime = TimeSpan.FromSeconds(1.0 / 60);
            font = Game.Content.Load<SpriteFont>(@"Arial");
            left = Game.Content.Load<Texture2D>(@"Screens/Test/freccia_l");
            right = Game.Content.Load<Texture2D>(@"Screens/Test/freccia_r");
            up = Game.Content.Load<Texture2D>(@"Screens/Test/freccia_u");
            down = Game.Content.Load<Texture2D>(@"Screens/Test/freccia_d");
            center = Game.Content.Load<Texture2D>(@"Screens/Test/portal");
            // UP
            // DOWN
            // LEFT
            // RIGHT
            // CENTER
            posizioni.Add(new Vector2(160, (StateManager.graphic.PreferredBackBufferHeight / 2) - left.Height * screenscale / 2));
            posizioni.Add(new Vector2(StateManager.graphic.PreferredBackBufferWidth - (160 + right.Width * screenscale), (StateManager.graphic.PreferredBackBufferHeight / 2) - right.Height * screenscale / 2));
            posizioni.Add(new Vector2((StateManager.graphic.PreferredBackBufferWidth / 2) - up.Width * screenscale / 2, 160));
            posizioni.Add(new Vector2((StateManager.graphic.PreferredBackBufferWidth / 2) - up.Width * screenscale / 2, StateManager.graphic.PreferredBackBufferHeight - (160 + down.Height * screenscale)));
            posizioni.Add(new Vector2(StateManager.graphic.PreferredBackBufferWidth / 2 - center.Width * screenscale / 2, StateManager.graphic.PreferredBackBufferHeight / 2 - center.Height * screenscale / 2));
            current = center;
            pos = posizioni.ElementAt(4);
            sm.Init();
            base.Initialize();
        }

        protected override void LoadContent()
        {
            float screenscale = (float)graphics.GraphicsDevice.Viewport.Width / 800f;
            SpriteScale = Matrix.CreateScale(screenscale, screenscale, 1);
        }

        public override void Update(GameTime gameTime)
        {
            if (OldState)
            {
                time += (float)gameTime.ElapsedGameTime.Milliseconds;


                if (isFirstime && (time > 2000f))
                {
                    sender.HIMStartAcquisition();
                    isFirstime = false;
                    time = 0f;
                }
                else if ((!isFirstime) && (time >= 8000f))
                {
                    if (stim)
                    {
                        switch (countSequence)
                        {
                            case 0:
                                // SU
                                sender.HIMTraining(TESTINGSEQUENCE["UP"]);
                                sm.SetFrequencies(9999, 9999, sender.Frequenze()[2], 9999);
                                pos = posizioni.ElementAt(2);
                                current = up;
                                break;
                            case 1:
                                // DX
                                sender.HIMTraining(TESTINGSEQUENCE["RIGHT"]);
                                sm.SetFrequencies(9999, sender.Frequenze()[1], 9999, 9999);
                                pos = posizioni.ElementAt(1);
                                current = right;
                                break;
                            case 2:
                                // GIU'
                                sender.HIMTraining(TESTINGSEQUENCE["DOWN"]);
                                sm.SetFrequencies(9999, 9999, 9999, sender.Frequenze()[3]);
                                pos = posizioni.ElementAt(3);
                                current = down;
                                break;
                            case 3:
                                // SX
                                sender.HIMTraining(TESTINGSEQUENCE["LEFT"]);
                                sm.SetFrequencies(sender.Frequenze()[0], 9999, 9999, 9999);
                                pos = posizioni.ElementAt(0);
                                current = left;
                                break;
                        }


                        sm.Start();
                        if (countSequence == 4) { XIsPressed(); }
                        else { countSequence++; }
                    }
                    else
                    {
                        // TODO: Add sender.
                        current = center;
                        pos = posizioni.ElementAt(4);
                        sm.SetFrequencies(0, 0, 0, 0);
                        sm.Stop();
                    }
                    time = 0;
                    stim = !stim;
                }
            }
            base.Update(gameTime);
        }
        protected override void Dispose(bool disposing)
        {
            Game.Content.Unload();
            Game.Services.RemoveService(typeof(Test));
            base.Dispose(disposing);
        }

        public void Detach()
        {
            // Detach the event and delete the list
            InputManagerService.EnterPressed -= new PressedEventHandler(SIsPressed);
            InputManagerService.SReleased -= new PressedEventHandler(SIsReleased);
            InputManagerService.XPressed -= new PressedEventHandler(XIsPressed);
            /*InputManagerService.EnterPressed -= new PressedEventHandler(EnterIsPressed);
            InputManagerService.EnterReleased -= new PressedEventHandler(EnterIsReleased);
            InputManagerService.TabPressed -= new PressedEventHandler(TabIsPressed);
            InputManagerService.UpPressed -= new PressedEventHandler(UpIsPressed);
            InputManagerService.DownPressed -= new PressedEventHandler(DownIsPressed);*/
            InputManagerService = null;
        }

        public override void Draw(GameTime gameTime)
        {
            //graphics.GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            SpriteFont c = Game.Content.Load<SpriteFont>("Arial");
            if (OldState == false)
            {
                //mySSVEP.DrawText(spriteBatch, "Arial", "Premere S per attivare stimolatori", new Vector2(300, 200));
                spriteBatch.DrawString(font, "Premere S per attivare stimolatori",
                   new Vector2(300, 200),
                   Color.Yellow,
                   0.0f,
                   new Vector2(0, 0),
                   screenscale * 1.2f,
                   SpriteEffects.None, 0);

                spriteBatch.DrawString(font, "X per tornare al menu.",
                   new Vector2(400, 320),
                   Color.Red,
                   0.0f,
                   new Vector2(0, 0),
                   screenscale * 1.2f,
                   SpriteEffects.None, 0);
            }
            else
            {
                spriteBatch.Draw(current, pos, null, Color.White, 0f, Vector2.Zero, screenscale, SpriteEffects.None, 0f);
            }
            spriteBatch.End();

            base.Draw(gameTime);
        }

        public void SIsPressed()
        {
            if (OldState)
            {
                sm.Stop();

            }
            else
            {
                sender.HIMRequestParams();
            }
        }

        public void SIsReleased()
        {
            OldState = !OldState;
        }

        public void XIsPressed()
        {
            sm.Stop();
            sm.Close();
            if (OnBack != null) { OnBack(); }
        }
    }
}

